package com.koudai.finance.utils;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

/**
 * @Description: excel工具类
 * @author: ls
 * @Date: 2020/5/25 19:46
 */
public class EasyExcelUtil {

    /**
     * 模型解析监听器
     */
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    private static class ModelExcelListener<E> extends AnalysisEventListener<E> {

        private List<E> dataList = new ArrayList<>();

        @Override
        public void invoke(E object, AnalysisContext context) {
            dataList.add(object);
        }

        @Override
        public void doAfterAllAnalysed(AnalysisContext context) {
        }
    }

    /**
     * @Description: 读取excel
     * @author: ls
     * @Date: 2020/5/26 13:58
     */
    public static <E> List<E> readExcel(InputStream inputStream, Class model, ExcelTypeEnum excelTypeEnum) {
        ModelExcelListener<E> listener = new ModelExcelListener<>();
        EasyExcel.read(inputStream, model, listener).excelType(excelTypeEnum).sheet().doRead();
        return listener.getDataList();
    }

    /**
     * @Description: 生成excel并下载
     * @author: ls
     * @Date: 2020/5/26 13:57
     */
    public static void writeExcel(HttpServletResponse response, List<? extends Object> data, String fileName, Class model) throws Exception {
        // 头的策略
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        //设置表头居中对齐
        headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontHeightInPoints((short) 10);
        // 字体
        headWriteCellStyle.setWriteFont(headWriteFont);
        headWriteCellStyle.setWrapped(true);
        // 内容的策略
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        //设置内容靠中对齐
        contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        // 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现
        HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
//        EasyExcel.write(new File("E:\\test.xlsx") , model).excelType(ExcelTypeEnum.XLSX).sheet("Sheet1").registerWriteHandler(horizontalCellStyleStrategy).doWrite(data);
        EasyExcel.write(getOutputStream(fileName, response), model).excelType(ExcelTypeEnum.XLSX).sheet("Sheet1").registerWriteHandler(horizontalCellStyleStrategy).doWrite(data);
    }

    /**
     * @Description: 设置输出流属性
     * @author: ls
     * @Date: 2020/5/26 13:59
     */
    private static OutputStream getOutputStream(String fileName, HttpServletResponse response) throws Exception {
        try {
            fileName = URLEncoder.encode(fileName, "UTF-8");
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf8");
            response.setHeader("Content-Disposition", "attachment; filename=" + fileName + ".xlsx");
            response.setHeader("Pragma", "public");
            response.setHeader("Cache-Control", "no-store");
            response.addHeader("Cache-Control", "max-age=0");
            return response.getOutputStream();
        } catch (IOException e) {
            throw new Exception("导出excel表格失败!", e);
        }
    }
}